package cn.edu.cuc.yjsy.admin.connection;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.osgi.framework.Bundle;

import cn.edu.cuc.yjsy.admin.Activator;
import cn.edu.cuc.yjsy.admin.util.ILogger;
import cn.edu.cuc.yjsy.admin.util.LoggerAdvisor;
import cn.edu.cuc.yjsy.admin.util.StudentAttributes;
import cn.edu.cuc.yjsy.database.Database;
import cn.edu.cuc.yjsy.database.DatabaseModelManager;
import cn.edu.cuc.yjsy.database.Field;
import cn.edu.cuc.yjsy.database.Table;


public abstract class AbstractConnection implements IConnection {
	
	private ILogger logger = new LoggerAdvisor(AbstractConnection.class);

	static final String TABLE_STUDENT = "student";	//$non-nls
	protected Database db = null;
	protected String tableName;
	protected static DatabaseModelManager dbManager = null;
	protected Connection conn = null;
	protected Statement st = null;
	
	protected AbstractConnection(){
		
	}
	
	public AbstractConnection(String configFile){
		try {
			dbManager = new DatabaseModelManager();
			Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
			String configPath = null;
	    	if (bundle != null){
	    		IPath path = null;
	    		path = new Path(FileLocator.toFileURL(bundle.getEntry("/")).getPath());
	    		configPath = path.toOSString() + File.separator + configFile;
	    	}
			dbManager.load(new Path(configPath));
			db = dbManager.getModel();
			fetchTableName();
			
			Class.forName(db.getDriver());
		} catch (ClassNotFoundException e) {
			logger.error("Register JDBC driver: " + db.getDriver());
		} catch (IOException e) {
			logger.error("Can't load database configuration");
			e.printStackTrace();
		}	
	}

	protected void fetchTableName() {
		EList tables = db.getTable();
		for(Iterator iter = tables.iterator(); iter.hasNext();){
			Table t = (Table)iter.next();
			if(t.getName().equals(TABLE_STUDENT)){
				tableName = t.getTableName();
				break;
			}
		}
	}
	
	public String getTableName(){
		return tableName;
	}
	
	public String getFieldName(int key){
		String keyword = StudentAttributes.getAttributeName(key);
		if(keyword != null){
			EList tables = db.getTable();
			for(Iterator iter = tables.iterator(); iter.hasNext();){
				Table t = (Table)iter.next();
				if(t.getName().equals(TABLE_STUDENT)){
					EList fields = t.getField();
					for(Iterator i = fields.iterator(); i.hasNext();){
						Field f = (Field)i.next();
						if(f.getName().equals(keyword))
							return f.getFieldName();
					}
				}
			}
		}
		return null;
	}
	
	public void executeStatement(String sql) throws SQLException{
		if(conn == null)
			connection();
		st = conn.createStatement();
		st.execute(sql);
	}

	/* (non-Javadoc)
	 * @see cn.edu.cuc.yjsy.admin.util.IConnection#executeQuery(java.lang.String)
	 */
	public ResultSet executeQuery(String sql) throws SQLException{
		ResultSet rs = null;		
		if(conn == null)
			connection();
		st = conn.createStatement();
		rs = st.executeQuery(sql);
		
		return rs;
	}
	
	/* (non-Javadoc)
	 * @see cn.edu.cuc.yjsy.admin.util.IConnection#dispose()
	 */
	public void dispose() throws SQLException{
		if (st != null){
			st.close();
			st = null;
		}
		if (conn != null){
			conn.close();
			conn = null;
		}
	}
	
	public String[] getTables() throws SQLException{
		List tables = new ArrayList();
		ResultSet rs = null;
		try{
			DatabaseMetaData metaData = conn.getMetaData();

			rs = metaData.getTables(null, null, "%", new String[]{"TABLE"});
			while(rs.next())
				tables.add(rs.getString("TABLE_NAME"));
		}finally{
			if(rs != null)
				rs.close();
		}
		
		return (String[])tables.toArray(new String[0]);
	}

	public abstract void connection() throws SQLException; 
}